﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Web;
using umbraco.BusinessLogic;
using Umbraco.Forms.Core;
using Umbraco.Forms.Core.Services;
using Umbraco.Forms.Data.Storage;

namespace Cultiv.RestContour
{
    public class SubmitContourForm
    {
        public static string CreateRecord()
        {
            var returnValue = "";

            if (string.IsNullOrEmpty(HttpContext.Current.Request["culture"]) == false)
                SetCulture(HttpContext.Current.Request["culture"]);

            const string jsonErrorStringStart = "{ \"errors\": [ ";
            const string jsonErrorStringEnd = " ] }";
            var jsonErrorString = jsonErrorStringStart;
            var numberOfErrors = 0;

            if (string.IsNullOrEmpty(HttpContext.Current.Request["formGuid"]))
            {
                const string errorString = "{ \"type\": \"input\", \"field\": \"formGuid\" }";
                jsonErrorString += numberOfErrors == 0 ? errorString : ", " + errorString;
                jsonErrorString += jsonErrorStringEnd;
                return Helper.EncodeForJavascript()
                    ? Helper.EncodeJsString("(" + jsonErrorString + ")")
                    : jsonErrorString;
            }

            var formGuid = HttpContext.Current.Request["formGuid"];

            int nodeId;
            if (string.IsNullOrEmpty(HttpContext.Current.Request["nodeId"]) ||
                int.TryParse(HttpContext.Current.Request["nodeId"], out nodeId) == false)
                nodeId = -1;

            var userIpAddress = string.IsNullOrEmpty(HttpContext.Current.Request["userIpAddress"])
                ? HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]
                : HttpContext.Current.Request["userIpAddress"];

            var fieldValues = new Dictionary<string, string>();

            using (var recordStorage = new RecordStorage())
            using (var formStorage = new FormStorage())
            {
                var form = formStorage.GetForm(new Guid(formGuid));

                using (var recordService = new RecordService(form))
                {
                    recordService.Open();

                    foreach (var f in recordService.Form.AllFields)
                    {
                        var field = f;
                        var currentFieldValue = HttpContext.Current.Request[field.Caption] ?? "";
                        var validation = new Regex(field.RegEx);

                        var fieldCaption = field.Caption;

                        if (validation.Match(currentFieldValue).Success == false && currentFieldValue != "")
                        {
                            var errorMessage = string.IsNullOrEmpty(form.InvalidErrorMessage)
                                ? field.InvalidErrorMessage
                                : form.InvalidErrorMessage;

                            var fieldErrorMessage = GetErrorMessage(errorMessage, field.Caption);
                            var errorString = "{ \"type\": \"validation\", \"field\": " + Helper.Enquote(fieldCaption) + ", \"errorMessage\": " + Helper.Enquote(fieldErrorMessage) + " }";
                            jsonErrorString += numberOfErrors == 0 ? errorString : ", " + errorString;
                            numberOfErrors += 1;
                            continue;
                        }

                        if (field.Mandatory && currentFieldValue == "")
                        {
                            var errorMessage = string.IsNullOrEmpty(form.RequiredErrorMessage)
                                ? field.RequiredErrorMessage
                                : form.RequiredErrorMessage;

                            var fieldErrorMessage = GetErrorMessage(errorMessage, field.Caption);
                            var errorString = "{ \"type\": \"required\", \"field\": " + Helper.Enquote(fieldCaption) + ", \"errorMessage\": " + Helper.Enquote(fieldErrorMessage) + " }";
                            jsonErrorString += numberOfErrors == 0 ? errorString : ", " + errorString;
                            numberOfErrors += 1;
                            continue;
                        }

                        fieldValues.Add(field.Caption, currentFieldValue);
                    }

                    if (numberOfErrors == 0)
                    {
                        var record = recordService.Record;

                        record.IP = userIpAddress;
                        record.UmbracoPageId = nodeId;
                        recordStorage.InsertRecord(record, form);

                        foreach (var f in recordService.Form.AllFields)
                        {
                            var field = f;
                            var currentFieldValue = fieldValues[field.Caption];

                            if (GetFieldType(field) == "CheckBox")
                            {
                                currentFieldValue = string.IsNullOrEmpty(currentFieldValue) ? "False" : "True";
                            }

                            if (GetFieldType(field) == "DatePicker" && string.IsNullOrEmpty(currentFieldValue))
                                continue;

                            var key = Guid.NewGuid();
                            var recordField = new RecordField
                            {
                                Field = field,
                                Key = key,
                                Record = record.Id,
                                Values = new List<object> { currentFieldValue }
                            };

                            using (var recordFieldStorage = new RecordFieldStorage())
                                recordFieldStorage.InsertRecordField(recordField);

                            record.RecordFields.Add(key, recordField);
                        }
                        recordService.Submit();
                        recordService.SaveFormToRecord();
                    }
                }
            }

            jsonErrorString += jsonErrorStringEnd;
            returnValue += jsonErrorString;

            returnValue = Helper.EncodeForJavascript()
                ? Helper.EncodeJsString("(" + returnValue + ")")
                : returnValue;

            if (numberOfErrors == 0)
                returnValue = Helper.EncodeForJavascript()
                                  ? Helper.EncodeJsString("({ \"success\": \"true\" }")
                                  : "{ \"success\": \"true\" }";

            return returnValue;
        }

        private static string GetFieldType(Field field)
        {
            return field.FieldType.ToString().Substring(field.FieldType.ToString().LastIndexOf(".") + 1);
        }

        private static string GetErrorMessage(string errorMessage, string fieldCaption)
        {
            var error = errorMessage.StartsWith("#")
                ? Helper.GetDictionaryItem(errorMessage.Substring(1))
                : errorMessage;

            fieldCaption = fieldCaption.StartsWith("#")
                               ? Helper.GetDictionaryItem(fieldCaption.Substring(1))
                               : fieldCaption;

            return string.Format(error, fieldCaption);
        }

        private static void SetCulture(string cultureName)
        {
            try
            {
                var culture = new CultureInfo(cultureName);
                System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
            }
            catch (Exception ex)
            {
                Log.Add(LogTypes.Error, -1, string.Format("SubmitContourForm - SetCulture exception: {0}", ex.Message));
            }
        }
    }
}